package dolphin.mt521.cam.ac.uk;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import dolphin.mt521.cam.ac.uk.Encode;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;

public class Microphone {

    private static byte[] buffer = null;
    private static byte[] array = null;
    private static int bytes = 128; //number of bytes to read each time
    private static int sampleRate = (int)Encode.getSampleRate();
    
    public static byte[] mic() {
        AudioRecord recorder = null;
        int toRead = Encode.getChunkSize()*bytes;       //1024*bytes for 64msec 16kHz samplerate
        int num = toRead*2;         //byte array twice as big as 16bit encoding
        buffer = new byte[num];
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        
        int bufferSize = AudioRecord.getMinBufferSize(sampleRate,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
        //bufferSize can be as low as 2 so increase
        if (bufferSize <= 2048) {
            bufferSize = 2048;
        }
        
        //needed bufferSize for last field in constructor for recorder, as follows:
        recorder = new AudioRecord( MediaRecorder.AudioSource.MIC,      //record from microphone
                                    sampleRate,                         //sample rate
                                    AudioFormat.CHANNEL_IN_MONO,        //guaranteed to work on all devices, alternative is "STEREO"
                                    AudioFormat.ENCODING_PCM_16BIT,     //must be 16bit, 8bit no longer supported
                                    num);                               //size of buffer written to
        recorder.startRecording();
        try {
            int read = 0;
            while (read<toRead) {
                read+=recorder.read(buffer,0,num); //returns an int saying how many bytes were read
                stream.write(buffer);
            }
        }
        catch (IOException e) {
            Log.e("Microphone","Couldn't read microphone data");
            return new byte[0];
        }
        recorder.stop();
        recorder.release();
        buffer = stream.toByteArray();
        
        //convert from 16bit to 8bit PCM by discarding lower 8 bits of every sample (every other array element),
        //but in little endian so discard first 8 bits
        array = new byte[toRead];
        for (int i=0, j=0; i<num; i++) {
            if ((i%2)!=0) {
                array[j] = buffer[i];
                j++;
            }
        }
        return array;
    }
    
}
